
package cz.czu.pef.DataModelling.dao;

import java.util.Collection;
import java.util.List;

import cz.czu.pef.common.CustomFilterField;
import cz.czu.pef.common.CustomSortField;


/**
 * Contains basic DAO operations (CRUD, count, countWithFilter, find*) for given Entity
 * 
 * @author Rostislav Stříbrný
 *
 * @param <T>
 */
public interface DaoBasic<T>
{

  /**
   * Retrieve entity form database, identified by its id
   * 
   * @param id
   * @return
   */
  public T getByStringId(String id);

  /**
   * Retrieve entity form database, identified by its id
   * 
   * @param id
   * @return
   */
  public T getById(long id);

  /**
   * Retrieve entity form database, identified by its id
   * 
   * @param id
   * @return
   */
  public T getByIdLocked(long id);

  /**
   * Updates already stored entity
   * 
   * @param entity
   * @return
   */
  public void persist(T entity);

  /**
   * Removes entity from database
   * 
   * @param entity
   * @return
   */
  public void remove(T entity);

  /**
   * Removes entity from database by its unique ID
   * 
   * @param idValue
   * @return
   */
  public void removeById(long idValue);

  /**
   * Merges an entity
   * 
   * @param entity
   * @return newly merged entity
   */
  public T merge(T entity);

  /**
   * Merges an entity using given unique attribName+value pair
   * 
   * @param attribNames - column name used for filtering
   * @param values - column value used for filtering
   * @param entity
   * @return newly merged entity
   */
  public T mergeUnique(final String attribName, final Object value, T entity);

  /**
   * Merges an entity using given unique list of attribName+value pairs
   * 
   * @param attribNames - column names used for filtering
   * @param values - column values used for filtering
   * @param entity
   * @return newly merged entity
   */
  public T mergeUniqueExt(final String[] attribNames, final Object[] values, T entity);

  /**
   * Returns number of stored entities
   * 
   * @return
   */
  public Long count();

  /**
   * Returns number of entities satisfying given criteria
   * 
   * @param filterFields
   * @return
   */
  public Long countWithFilter(List<CustomFilterField> filterFields);

  public List<T> findByAttributeIn(final String attribName, final Collection<? extends Object> value);

  public List<T> findByAttribute(final String attribName, final Object value);

  public T findByAttributeUniqueResult(final String attribName, final Object value);

  /**
   * Returns all stored entities
   * 
   * @return
   */
  public List<T> findAll();

  /**
   * Returns all entities which are stored between given the firstRow and endRow rows (inclusive)
   * 
   * @param firstRow
   * @param endRow
   * @return
   */
  public List<T> findAllByRange(Integer firstRow, Integer endRow);

  /**
   * Returns all entities which:
   * - are stored between given the firstRow and endRow rows (inclusive)
   * - are satisfying given criteria defined by filterFields
   * 
   * @param firstRow
   * @param endRow
   * @param filterFields
   * @return
   */
  public List<T> findAllByRangeWithFilter(Integer firstRow, Integer endRow, List<CustomFilterField> filterFields);

  /**
   * Returns all entities which:
   * - are stored between given the firstRow and endRow rows (inclusive)
   * - are satisfying given criteria defined by filterFields
   * 
   * The result is sorted according to entered sortFields.
   * 
   * @param firstRow
   * @param endRow
   * @param filterFields
   * @param sortFields
   * @return
   */
  public List<T> findAllByRangeWithFilterAndSort(Integer firstRow, Integer endRow, List<CustomFilterField> filterFields, List<CustomSortField> sortFields);
}
